#include <gtk/gtk.h>
#include <stdio.h>

#include "gtkutils.h"
#include "socketutils.h"

void sayHello() {
    printf("hello word\n");
}

GtkEntryBuffer *host_entry_buffer;
GtkEntryBuffer *port_entry_buffer;
GtkTextBuffer *text_buffer;

GSList *sockets = NULL;

void to_send(TcpSocket *socket) {
    GtkTextIter start, end;
    gtk_text_buffer_get_start_iter(text_buffer, &start);
    gtk_text_buffer_get_end_iter(text_buffer, &end);
    char *text = textBufferGetText(text_buffer, &start, &end, true);
    if (text) {
        tcpSocketWrite(socket, text, strlen(text));
        free(text);
    }
}

void handle_to_send(TcpSocket *server) {
    TcpSocket *client = g_new0(TcpSocket, 1);
    // TcpSocket client = {0};
    while (socketAccept(server, client)) {
        sockets = g_slist_append(sockets, client);
        to_send(client);
    }
}

createSignalObjectFunc(text_view_changed, GtkTextBuffer) {
    for (GSList *iter = sockets; iter; iter = iter->next) {
        to_send((TcpSocket*)iter->data);
    }
}

createSignalObjectFunc(clicked_action_start_server, TcpSocket) { 
    const char *text = entryBufferGetText(port_entry_buffer);
    if (text) {
        int port = atoi(text);
        if (createTcpSocketServer(user_data, port)) {
            // TcpSocket *client = g_new0(TcpSocket, 1);
            
            pthread_t p;
            pthread_create(&p, NULL, (void*)handle_to_send, user_data);
        }
    }
}

void handle_to_receiver(TcpSocket *socket) {
    const char *text_host = entryBufferGetText(host_entry_buffer);
    const char *text_port = entryBufferGetText(port_entry_buffer);

    if (text_host && text_port) {
        int port = atoi(text_port);
        if (createTcpSocketWithHostPort(socket, text_host, port)) {
            if (socketConnect(socket, &socket->address, sizeof(socket->address))) {
                char buffer[10000] = {0};
                while (tcpSocketRead(socket, buffer, 10000)) {
                    textBufferSetText(text_buffer, buffer, strlen(buffer));
                }
            }
        }
    }
}

createSignalObjectFunc(clicked_action_connect, TcpSocket) {
    pthread_t p;
    pthread_create(&p, NULL, (void*)handle_to_receiver, user_data);
}

static void activate(GtkApplication *app, gpointer user_data) {
    GtkWindow *window;

    window = createWindowWithTitleSize(app, "GTK Chat", 600, 300);

    host_entry_buffer = createEntryBufferWithText("localhost");
    port_entry_buffer = createEntryBufferWithText("8080");
    text_buffer = createTextBuffer(NULL);


    TcpSocketServer *tcpserver = g_new0(TcpSocketServer, 1);
    TcpSocket *client = g_new0(TcpSocket, 1);
    TcpSocket *tcpclient = g_new0(TcpSocket, 1);

    GtkTextView *text_view = createTextViewWithTextBuffer(text_buffer);

    GtkBox *mainbox = createBoxWithVerticalAppends(5, 
        createBoxWithHorizntalMarginAlignAppends(5, 5, ACENTER,
            createLabel("主机:"),
            createEntryWithEntryBuffer(host_entry_buffer),
            createLabel("端口:"),
            createEntryWithEntryBuffer(port_entry_buffer),
            createButtonAction(tcpserver, "启动服务", clicked_action_start_server),
            createButtonAction(tcpclient, "连接", clicked_action_connect),
            NULL
        ),
        createWidgetVerticalExpand(text_view, true),
        NULL
    );

    connectTargetAction(text_buffer, text_buffer, "changed", text_view_changed);

    setWindowChild(window, mainbox);
    showWindow(window);
}

int	main(int argc, char **argv) {

    GtkApplication *app;
    int status;

    app = createApplicationConnectActivate("gtk.example.template", 
                                G_APPLICATION_FLAGS_NONE, activate);
    status = runApplication(app, argc, argv);
    objectUnref(app);

    return status;
}

